package com.sharding.config;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author wl
 * @Description: 利用AOP切面实现数据源的动态切换
 * @date 2018/12/1417:01
 */
@Aspect
@Component
@Order(-100)//必须先加载
public class DynamicDataSourceAspect {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Before("@annotation(DS)")
    public void beforeSwitchDS(JoinPoint point){
        //获得当前访问的class
        Class<?> className = point.getTarget().getClass();
        //获得访问的方法名
        String methodName = point.getSignature().getName();
        logger.info("访问的方法名:"+methodName);
        //得到方法的参数的类型
        Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
        String dataSource = DataSourceContextHolder.DEFAULT_DS;
        try {
            // 得到访问的方法对象
            Method method = className.getMethod(methodName, argClass);
            // 判断是否存在@DS注解
            if (method.isAnnotationPresent(DS.class)) {
                DS annotation = method.getAnnotation(DS.class);
                // 取出注解中的数据源名
                dataSource = annotation.value();
                logger.info("数据源名:"+dataSource);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        logger.info("设置数据源:"+dataSource);
        // 切换数据源
        DataSourceContextHolder.setDB(dataSource);
    }

    @After("@annotation(DS)")
    public void afterSwitchDS(JoinPoint point){
        logger.info("清空DB");
        DataSourceContextHolder.clearDB();
    }
}
